<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

namespace Poodle\Auth\Provider;

class Database extends \Poodle\Auth\Provider
{

	public function getAction(array $credentials=array())
	{
		$value=null;
		if (!empty($credentials['openid_identifier'])) $value = $credentials['openid_identifier'];
		if (!empty($credentials['auth_claimed_id']))   $value = $credentials['auth_claimed_id'];
		return new \Poodle\Auth\Result\Form(
			array(
				array('name'=>'auth_claimed_id', 'type'=>'text',     'label'=>'Username', 'value'=>$value),
				array('name'=>'auth_password',   'type'=>'password', 'label'=>'Password'),
			),
			'?auth='.$this->id,
			'auth-database'
		);
	}

	public function authenticate($credentials)
	{
		if (!isset($credentials['auth_claimed_id']) && !isset($credentials['auth_password'])) {
			return $this->getAction($credentials);
		}

		if (!isset($credentials['auth_claimed_id']) || !isset($credentials['auth_password'])) {
			return new \Poodle\Auth\Result\Error(self::ERR_FAILURE);
		}

		if (empty($credentials['auth_password']) || empty($credentials['auth_claimed_id'])) {
			return new \Poodle\Auth\Result\Error(self::ERR_CREDENTIAL_INVALID);
		}

		$SQL = \Poodle::getKernel()->SQL;
		$id_secure = $SQL->quote(self::secureClaimedID($credentials['auth_claimed_id']));
		$provider = $SQL->uFetchAssoc("SELECT
			identity_id,
			auth_password password
		FROM {$SQL->TBL->auth_identities} ua
		INNER JOIN {$SQL->TBL->auth_providers} USING (auth_provider_id)
		WHERE auth_claimed_id={$id_secure}
		  AND auth_provider_id={$this->id}
		  AND auth_provider_mode>0");
		if (!$provider) {
			return new \Poodle\Auth\Result\Error(self::ERR_CREDENTIAL_INVALID, 'A database record was not found');
		}

		// Verify password
		if (!$this->isValidPassword($provider['identity_id'], $credentials['auth_password'], $provider['password']))
		{
			return new \Poodle\Auth\Result\Error(self::ERR_CREDENTIAL_INVALID, 'A database record with the supplied claimed_id ('.$credentials['auth_claimed_id'].') was found but, the password verification failed.');
		}

		# Cookie is correct so check the data
		# Lookup user in the database
		$user = \Poodle\Identity\Search::byID($provider['identity_id']);
		if (!$user)
		{
			return new \Poodle\Auth\Result\Error(self::ERR_IDENTITY_NOT_FOUND, 'A database record with the supplied identity_id ('.$provider['identity_id'].') could not be found.');
		}

		return new \Poodle\Auth\Result\Success($user);
	}

	/**
	 * Checks to see if the given password is valid for the given identity.
	 *
	 * @param integer $identity_id The identity to check the password for
	 * @param string $plain_password The password to check
	 * @param string $auth_password The password from the database (optional)
	 *
	 * @returns boolean true|false depending on validity
	 */
	public function isValidPassword($identity_id, $plain_password, $auth_password=null)
	{
		$identity_id = (int)$identity_id;

		// No identity_id or plain_password given
		if (!$identity_id || !$plain_password) {
			return false;
		}

		if (!$auth_password)
		{
			// Retrieve the current identity password
			$SQL = \Poodle::getKernel()->SQL;
			$auth = $SQL->uFetchRow("SELECT
				auth_password
			FROM {$SQL->TBL->auth_identities} ua
			INNER JOIN {$SQL->TBL->auth_providers} USING (auth_provider_id)
			WHERE identity_id = {$identity_id}
			  AND auth_provider_id = {$this->id}
			  AND auth_provider_mode > 0");
			$auth_password = $auth[0];
		}

		// Verify given password
		list($algo, $password) = explode(':', $auth_password, 2);
		return ($algo && $password
		 && (\Poodle\Hash::available($algo)
			? \Poodle\Hash::verify($algo, $plain_password, $password)
			: (class_exists($algo) && $algo::verify($plain_password, $password))));
	}
}
